from neo4j import GraphDatabase
import time
from loguru import logger

class Neo4jServices:
    #对外的接口，由Web服务进行调用转化为Rest API
    def __init__(self, uri, user, password,db_name='neo4jnew'):
        self.driver = GraphDatabase.driver(uri, auth=(user, password))
        self.db_name = db_name

    def close(self):
        self.driver.close()

    def clear_data(self):
        def work(tx):
            tx.run("""
            MATCH (n) DETACH DELETE n
            """)
        with self.driver.session(database=self.db_name) as session:
            session.execute_write(work)
    # 创建节点
    def create_node(self, label, data):
        with self.driver.session() as session:
            # 构建创建节点的 Cypher 查询
            query = (
                     f"MERGE (node:{label} {{"
                     + ', '.join([f"{key}: ${key}" for key in data.keys()])
                     + "})"
            )
            # 执行查询
            session.run(query, parameters=data)


    # 查询节点
    def get_nodes(self, nodeId,label='论文'):
         with self.driver.session() as session:
             query = f"MATCH (n:{label}) WHERE elementId(n)='{nodeId}' RETURN n.original_id"
             result = session.run(query)
             # 获取结果
             original_ids=set()
             cnt = 0
             for record in result:
                 cnt = cnt+1
                 original_ids.add(record["n.original_id"])
         return original_ids,len(original_ids)

    def save_dict_to_neo4j(self, data_list, label):
        """
        转存数据
        """
        for data in data_list:
            # 数据处理
            properties = {}
            for key, value in data.items():
                properties[key] = value
            properties['db_name'] = label
            # 创建节点
            self.create_node(label, properties)

    def delete_relationship(self,src_id,dst_id):
        if dst_id:
            query = f"""MATCH (n1)-[r]->(n2) WHERE elementId(n1)='{src_id}' AND elementId(n2)='{dst_id}' DELETE r"""
        else:
            query = f"""MATCH (n1)-[r]-() WHERE elementId(n1)='{src_id}' DELETE r"""
        with self.driver.session() as session:
            session.run(query)

    def set_node_props(self, label,name,data):
        with self.driver.session() as session:
            query =  "Match (node:"+label+") "+" Where node.name='"+str(name)+"' set node += $data"
            session.run(query, data=data)

    def create_node_if_exits_update(self,lable,name_):
        def node_work(tx,lable,name_):
            query = "MERGE(:{}{name: {}})".format(lable,name_)
            tx.run(query)
        with self.driver.session(database=self.db_name) as session:
            session.execute_write(lable,name_)

    def create_relationship_between_nodes(self,node1,node2,lable1,lable2,r,description=''):
        def work(tx):
            query = "MATCH (a:{}{{name:$node1}}), (b:{}{{name:$node2}}) MERGE (a)-[rel:{}]->(b) set rel.description='{}'".format(lable1,lable2,r,description)
            tx.run(query,node1=node1,node2=node2,r=r,description=description)
        with self.driver.session(database=self.db_name) as session:
            session.execute_write(work)
